package com.xingkeduo.service.api.activity.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.xingkeduo.dao.TActivityDaysMapper;
import com.xingkeduo.dao.TActivityMapper;
import com.xingkeduo.feign.HairstyleFeignService;
import com.xingkeduo.model.example.TActivityDaysExample;
import com.xingkeduo.model.example.TActivityExample;
import com.xingkeduo.model.example.TActivityExample.Criteria;
import com.xingkeduo.model.param.ActivityParam.ActivityModeEnum;
import com.xingkeduo.model.param.ActivityParam.ActivityTypeEnum;
import com.xingkeduo.model.param.MarketingParam.MarketingStatusEnum;
import com.xingkeduo.model.po.TActivity;
import com.xingkeduo.model.po.TActivityDays;
import com.xingkeduo.model.vo.ActivityDaysResponseVo;
import com.xingkeduo.model.vo.api.ActivityApiResponseVo;
import com.xingkeduo.service.api.activity.StoreActivityService;
import com.xingkeduo.service.api.marketing.impl.StoreServiceImpl;
import com.xingkeduo.util.Constant;
import com.xingkeduo.util.DateUtils;
import com.xingkeduo.util.tool.ResponseMessage;
@Service
public class StoreActivityServiceImpl implements StoreActivityService {
	Logger logger = LoggerFactory.getLogger(StoreServiceImpl.class);
	@Autowired
	TActivityDaysMapper tActivityDaysMapper;
	@Autowired
	HairstyleFeignService hairstyleFeignService;
	@Autowired
	TActivityMapper tActivityMapper;

	@Override
	public ResponseMessage getStoreHelpPaymentActivityList(Long storeId) {
		List<ActivityApiResponseVo> returnList = buildStoreActivityInfoByStoreIdsAndActivityType(storeId.toString(),
				ActivityTypeEnum.HELP_PAYMENT.getStatusType(), Boolean.FALSE, Boolean.TRUE);
		return ResponseMessage.ok(returnList);
	}

	@Override
	public ResponseMessage getStoreActivityDetail(Long storeId) {
		List<ActivityApiResponseVo> returnList = buildStoreActivityInfoByStoreIdsAndActivityType(storeId.toString(),
				ActivityTypeEnum.HELP_PAYMENT.getStatusType(), Boolean.TRUE, Boolean.FALSE);
		return ResponseMessage.ok(returnList);
	}

	@Override
	public ResponseMessage getBatchStoreActivityDetail(String storeIds) {
		if (storeIds.startsWith(",")) {
			storeIds = storeIds.substring(1, storeIds.length());
		}
		String[] storeIdArray = storeIds.split(",");
		Map<String, List<ActivityApiResponseVo>> returnMap = new HashMap();
		if (storeIdArray.length == 0) {
			return ResponseMessage.ok(returnMap);
		}
		for (int i = 0; i < storeIdArray.length; i++) {
			List<ActivityApiResponseVo> returnList = buildStoreActivityInfoByStoreIdsAndActivityType(storeIdArray[i],
					ActivityTypeEnum.HELP_PAYMENT.getStatusType(), Boolean.TRUE, Boolean.FALSE);
			returnMap.put(storeIdArray[i].toString(), returnList);
		}
		return ResponseMessage.ok(returnMap);
	}

	/**
	 * 
	 * @Title: buildStoreActivityInfoByStoreIdsAndActivityType
	 * @Description: 构建活动数据
	 * @param @param  storeIds 门店id
	 * @param @param  activityType 活动类型
	 * @param @param  hasExcludeActivityType 是否排除该活动 是 查询不包含该活动类型数据，否 查询包含该活动类型数据
	 * @param @param  hasReturnPreferentialDate 是否返回优惠时间段 是返回，否不返回
	 * @param @return 设定文件
	 * @return List<ActivityApiResponseVo> 返回类型
	 * @throws @author lixin
	 * @date May 7, 2019 5:04:47 PM
	 */
	private List<ActivityApiResponseVo> buildStoreActivityInfoByStoreIdsAndActivityType(String storeIds,
			String activityType, Boolean hasExcludeActivityType, Boolean hasReturnPreferentialDate) {
		List<TActivity> activityList = new ArrayList<TActivity>();
		// 查询设置部分门店的代购活动中是否包含本门店
		if (storeIds.startsWith(",")) {
			storeIds = storeIds.substring(1, storeIds.length());
		}
		String[] storeIdArray = storeIds.split(",");
		for (String storeId : storeIdArray) {
			TActivityExample someActivityExample = new TActivityExample();
			Criteria criteria = someActivityExample.createCriteria();
			criteria.andStartTimeLessThanOrEqualTo(new Date()).andEndTimeGreaterThanOrEqualTo(new Date())
					.andActivityModeEqualTo(ActivityModeEnum.STORE.getCode())
					.andStatusEqualTo(MarketingStatusEnum.UP.getCode()).andStoreIdsLike("%," + storeId + ",%");
			if (hasExcludeActivityType) {
				criteria.andActivityTypeNotEqualTo(activityType);
			}
			if (!hasExcludeActivityType) {
				criteria.andActivityTypeEqualTo(activityType);
			}
			List<TActivity> someActivityList = tActivityMapper.selectByExample(someActivityExample);
			if (!CollectionUtils.isEmpty(someActivityList)) {
				activityList.addAll(someActivityList);
			}
		}
		// 查询设置全门店的代购活动中是否包含本门店
		TActivityExample allActivityExample = new TActivityExample();
		Criteria criteria = allActivityExample.createCriteria();
		criteria.andActivityTypeNotEqualTo(activityType).andStartTimeLessThanOrEqualTo(new Date())
				.andActivityModeEqualTo(ActivityModeEnum.STORE.getCode()).andEndTimeGreaterThanOrEqualTo(new Date())
				.andStatusEqualTo(MarketingStatusEnum.UP.getCode()).andStoreIdsEqualTo("0");
		if (hasExcludeActivityType) {
			criteria.andActivityTypeNotEqualTo(activityType);
		}
		if (!hasExcludeActivityType) {
			criteria.andActivityTypeEqualTo(activityType);
		}
		List<TActivity> allActivityList = tActivityMapper.selectByExample(allActivityExample);
		if (!CollectionUtils.isEmpty(allActivityList)) {
			activityList.addAll(allActivityList);
		}
		return buildResponseDateInfo(hasReturnPreferentialDate, activityList);
	}

	@Override
	public ResponseMessage getBatchHairdresserActivity(Long storeId, String hairStyleIds) {
		List<ActivityApiResponseVo> returnList = buildStoreHairActivityInfoByStoreIdsAndActivityMode(storeId,
				hairStyleIds, ActivityModeEnum.HAIRDRESSER.getCode(), Boolean.FALSE, Boolean.FALSE);
		return ResponseMessage.ok(returnList);
	}

	@Override
	public ResponseMessage getHairdresserActivity(Long storeId, Long hairStyleId) {
		List<ActivityApiResponseVo> returnList = buildStoreHairActivityInfoByStoreIdsAndActivityMode(storeId,
				hairStyleId.toString(), ActivityModeEnum.HAIRDRESSER.getCode(), Boolean.FALSE, Boolean.TRUE);
		return ResponseMessage.ok(returnList);
	}

	/**
	 * 
	 * @Title: buildStoreHairActivityInfoByStoreIdsAndActivityMode
	 * @Description: 构建店铺发型师活动标签
	 * @param @param  storeId
	 * @param @param  hairStyleIds
	 * @param @param  activityMode
	 * @param @param  hasExcludeActivityMode
	 * @param @param  hasReturnPreferentialDate
	 * @param @return 设定文件
	 * @return List<ActivityApiResponseVo> 返回类型
	 * @throws @author lixin
	 * @date May 7, 2019 5:40:14 PM
	 */
	private List<ActivityApiResponseVo> buildStoreHairActivityInfoByStoreIdsAndActivityMode(Long storeId,
			String hairStyleIds, Integer activityMode, Boolean hasOnlyActivityMode, Boolean hasReturnPreferentialDate) {
		List<TActivity> activityList = new ArrayList<TActivity>();
		if (hairStyleIds.startsWith(",")) {
			hairStyleIds = hairStyleIds.substring(1, hairStyleIds.length());
		}
		String[] stringArray = hairStyleIds.split(",");
		Long[] longArray = (Long[]) ConvertUtils.convert(stringArray, Long.class);
		List<Long> listArray = new ArrayList<Long>(longArray.length);
		Collections.addAll(listArray, longArray);
		// 查询设置部分门店的活动中是否包含本门店
		TActivityExample someActivityExample = new TActivityExample();
		Criteria criteria = someActivityExample.createCriteria();
		criteria.andStartTimeLessThanOrEqualTo(new Date()).andEndTimeGreaterThanOrEqualTo(new Date())
				.andStatusEqualTo(MarketingStatusEnum.UP.getCode()).andHairStyleIdIn(listArray)
				.andStoreIdsLike("%," + storeId + ",%");
		if (hasOnlyActivityMode) {
			criteria.andActivityModeNotEqualTo(activityMode);
		}
		List<TActivity> someActivityList = tActivityMapper.selectByExample(someActivityExample);
		if (!CollectionUtils.isEmpty(someActivityList)) {
			activityList.addAll(someActivityList);
		}
		// 查询设置全门店的活动中是否包含本门店
		TActivityExample allActivityExample = new TActivityExample();
		Criteria allCriteria = allActivityExample.createCriteria();
		allCriteria.andStartTimeLessThanOrEqualTo(new Date()).andEndTimeGreaterThanOrEqualTo(new Date())
				.andStatusEqualTo(MarketingStatusEnum.UP.getCode()).andHairStyleIdIn(listArray).andStoreIdsEqualTo("0");
		if (hasOnlyActivityMode) {
			allCriteria.andActivityModeNotEqualTo(activityMode);
		}
		List<TActivity> allActivityList = tActivityMapper.selectByExample(allActivityExample);
		if (!CollectionUtils.isEmpty(allActivityList)) {
			activityList.addAll(allActivityList);
		}
		return buildResponseDateInfo(hasReturnPreferentialDate, activityList);
	}

	private List<ActivityApiResponseVo> buildResponseDateInfo(Boolean hasReturnPreferentialDate,
			List<TActivity> activityList) {
		// 返回封装数据
		List<ActivityApiResponseVo> returnList = Lists.transform(activityList,
				new Function<TActivity, ActivityApiResponseVo>() {
					@Override
					public ActivityApiResponseVo apply(TActivity activity) {
						ActivityApiResponseVo activityApiResponseVo = new ActivityApiResponseVo();
						BeanUtils.copyProperties(activity, activityApiResponseVo);
						// 有额外设置活动时间
						if (hasReturnPreferentialDate // 是否需要下发优惠活动时间
								&& StringUtils.isNotBlank(activity.getWeekHourIds())// 是否有优惠时间
								&& (!"0".equals(activity.getWeekHourIds()))) {// 优惠时间不是全天
							// 查询活动时刻
							TActivityDaysExample activityDaysExample = new TActivityDaysExample();
							activityDaysExample.createCriteria().andActivityIdEqualTo(activity.getId())
									.andActivityTypeEqualTo(activity.getActivityMode())
									.andStatusEqualTo(Constant.STATUS_YES);
							List<TActivityDays> activityDays = tActivityDaysMapper.selectByExample(activityDaysExample);
							List<ActivityDaysResponseVo> activityDaysResponseVoList = Lists.transform(activityDays,
									new Function<TActivityDays, ActivityDaysResponseVo>() {
										@Override
										public ActivityDaysResponseVo apply(TActivityDays activityDays) {
											ActivityDaysResponseVo activityDaysResponseVo = new ActivityDaysResponseVo();
											BeanUtils.copyProperties(activityDays, activityDaysResponseVo);
											return activityDaysResponseVo;
										}
									});
							activityApiResponseVo.setActivityDays(activityDaysResponseVoList);
						}
						return activityApiResponseVo;
					}
				});
		return returnList;
	}

	@Override
	public ResponseMessage getStoreActivitySummaryInfo(Long storeId) {
		Map returnMap = new HashMap();
		List<ActivityApiResponseVo> activityList = buildStoreActivityInfoByStoreIdsAndActivityType(storeId.toString(),
				ActivityTypeEnum.HELP_PAYMENT.getStatusType(), Boolean.TRUE, Boolean.FALSE);
		if (CollectionUtils.isEmpty(activityList)) {
			returnMap.put("activityCount", 0);
			return ResponseMessage.ok();
		}
		String day = DateUtils.getDayofweek()+"";
		List<ActivityApiResponseVo> returnList = activityList.stream().filter(activity->activity.getWeekHourIds().contains(day)).collect(Collectors.toList());
		if (CollectionUtils.isEmpty(returnList)) {
			returnMap.put("activityCount", 0);
			return ResponseMessage.ok();
		}
		returnMap.put("activityCount", returnList.size());
		if (returnList.size() == 1) {
			ActivityApiResponseVo responseVo = returnList.get(0);
			returnMap.put("activityInfo", responseVo);
		}
		return ResponseMessage.ok(returnMap);
	}

	@Override
	public ResponseMessage getHairdresserActivitySummaryInfo(Long storeId, List<Long> hairdresserIds) {
		Map returnMap = new HashMap();
		List<ActivityApiResponseVo> returnList = buildStoreHairActivityInfoByStoreIdsAndActivityMode(storeId,
				StringUtils.join(hairdresserIds, ","), ActivityModeEnum.HAIRDRESSER.getCode(), Boolean.FALSE,
				Boolean.FALSE);
		if (CollectionUtils.isEmpty(returnList)) {
			for (Long hairStyleId : hairdresserIds) {
				returnMap.put(hairStyleId.toString(), "false");
			}
			return ResponseMessage.ok(returnMap);
		}
		for (ActivityApiResponseVo responseVo : returnList) {
			returnMap.put(responseVo.getHairStyleId().toString(), "true");
		}
		return ResponseMessage.ok(returnMap);
	}
}
